package cn.com.blackboard.DataModule4B2.BBDataUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import blackboard.data.ValidationException;
import blackboard.data.category.BbCourseCategory;
import blackboard.data.role.PortalRole;
import blackboard.data.user.User;
import blackboard.persist.Id;
import blackboard.persist.KeyNotFoundException;
import blackboard.persist.PersistenceException;
import blackboard.persist.category.CourseCategoryDbLoader;
import blackboard.persist.category.CourseCategoryDbPersister;
import blackboard.persist.role.PortalRoleDbLoader;
import blackboard.persist.role.PortalRoleDbPersister;
import blackboard.persist.user.UserDbLoader;
import blackboard.portal.servlet.PortalConfig;
import cm.com.blackboard.DataModule4B2.customizeConfigUtils.CommonConfigLoader;
import cm.com.blackboard.DataModule4B2.customizeConfigUtils.DataSourceKeyUtil;
import cm.com.blackboard.DataModule4B2.customizeConfigUtils.ExtentionAttributeUtil;
import cn.com.blackboard.DataModule4B2.model.DepartmentInfo;
import cn.com.blackboard.DataModule4B2.util.BatchResultModel.Status;

public class DepartmentUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(DepartmentUtil.class);
	
	private static final String defaultDepartmentName = CommonConfigLoader.getDefaultDepartmentName();
	
	private static PortalRoleDbLoader portalRoleDbLoader = null;
	private static PortalRoleDbPersister portalRoleDbPersister = null;
	static {
		try {
			portalRoleDbLoader = PortalRoleDbLoader.Default.getInstance();
			portalRoleDbPersister = PortalRoleDbPersister.Default.getInstance();
		} catch (PersistenceException e) {
			logger.info("error in DepartmentUtil init PortalRoleDbLoader/portalRoleDbPersister"); 
		}
	}
	
	private static CourseCategoryDbLoader courseCategoryDbLoader = null;
	private static CourseCategoryDbPersister courseCategoryDbPersister = null;
	static {
		try {
			courseCategoryDbLoader = CourseCategoryDbLoader.Default.getInstance();
			courseCategoryDbPersister = CourseCategoryDbPersister.Default.getInstance();
		} catch (PersistenceException e) {
			logger.info("error in DepartmentUtil init CourseCategoryLoader"); 
		}
	}
	
	private static UserDbLoader userDbLoader = null;
	static {
		try {
			userDbLoader = UserDbLoader.Default.getInstance();
		} catch (PersistenceException e) {
			logger.info("error in DepartmentUtil init UserDbLoader"); 
		}
	}
	
	
	private static boolean isPortal = false;
	static {
		isPortal = PortalConfig.isDynamicPortal();
	}
	
	public static boolean isPortal(){
		return isPortal;
	}
	
	public static Status importDepartment(DepartmentInfo departmentInfo){
		String departmentId = departmentInfo.getDepartmentId();
		String departmentName = departmentInfo.getDepartmentName();
		boolean flagPortalSuccess = false;
		if(isPortal()){
			logger.info("portal version import department as portalRole");
			PortalRole pr = new PortalRole();
			departmentId = appendSilkPortalRoleSuffix(departmentId);
			pr.setRoleID(departmentId);
			pr.setRoleName(departmentName);
			if(ExtentionAttributeUtil.hasExtention(pr, departmentInfo)){
				ExtentionAttributeUtil.setExtentionAttribute(pr, departmentInfo);
			}
			DataSourceKeyUtil.setDataSrouceKey(pr, departmentInfo);
			try {
				portalRoleDbPersister.persist(pr);
				flagPortalSuccess = true;
			} catch (PersistenceException e) {
				logger.info("error in DepartmentUtil import as portalRole"); 
				e.printStackTrace();
				return Status.SubRelationFailed;
			} catch (ValidationException e) {
				logger.info("invalid in DepartmentUtil import as portalRole"); 
				e.printStackTrace();
				return Status.SubRelationFailed;
			}
		}
		departmentId = appendSilkCategorySuffix(departmentInfo.getDepartmentId());
		
		logger.info("normal version import department as courseCategory");
		BbCourseCategory bbcourseCategory = new BbCourseCategory();
		bbcourseCategory.setBatchUid(departmentId);
		bbcourseCategory.setTitle(departmentName);
		if(ExtentionAttributeUtil.hasExtention(bbcourseCategory, departmentInfo)){
			ExtentionAttributeUtil.setExtentionAttribute(bbcourseCategory, departmentInfo);
		}
		DataSourceKeyUtil.setDataSrouceKey(bbcourseCategory, departmentInfo);
		try {
			courseCategoryDbPersister.persist(bbcourseCategory);
			return Status.ImportSuccess;
		} catch (PersistenceException e) {
			logger.info("error in DepartmentUtil import as courseCategory"); 
			if(flagPortalSuccess)
				return Status.PortalSuccessButCatalogFailed;
			return Status.ImportFailed;
		} catch (ValidationException e) {
			logger.info("invalid in DepartmentUtil import as courseCategory"); 
			if(flagPortalSuccess)
				return Status.PortalSuccessButCatalogFailed;
			return Status.ImportFailed;
		}			
	}
	
	public static Id getPortalIdByDepartmentId(String departmentId){
		assert isPortal();		
		departmentId = appendSilkPortalRoleSuffix(departmentId);
		try {
			return portalRoleDbLoader.loadByRoleId(departmentId).getId();
		} catch (KeyNotFoundException e) {
			logger.info("DepartmentUtil getPortalIdByDepartmentId "+departmentId+" can't find department, maybe the department is not imported");
			return null;
		} catch (PersistenceException e) {
			logger.info("DepartmentUtil getPortalIdByDepartmentId can't find department, maybe the department is not imported");
			return null;
		}
	}
	
	public static Id getCategoryIdByDepartmentId(String departmentId){
		assert !isPortal();		
		departmentId = appendSilkCategorySuffix(departmentId);
		try {
			return courseCategoryDbLoader.loadByBatchUid(departmentId).getId();
		} catch (KeyNotFoundException e) {
			logger.info("DepartmentUtil getCategoryIdByDepartmentId "+departmentId+" can't find department, maybe the department is not imported");
			return null;
		} catch (PersistenceException e) {
			logger.info("DepartmentUtil getCategoryIdByDepartmentId can't find department, maybe the department is not imported");
			return null;
		}
	}
	
	public static String getDepartmentNameById(String departmentId){
		try{
			if(isPortal()){
				departmentId = appendSilkPortalRoleSuffix(departmentId);
				logger.info("DepartmentUtil getDepartmentName as portalRoleName");
				return portalRoleDbLoader.loadByRoleId(departmentId).getRoleName();
			}
			else{
				departmentId = appendSilkCategorySuffix(departmentId);
				logger.info("DepartmentUtil getDepartmentName as categoryTitle");
				return courseCategoryDbLoader.loadByBatchUid(departmentId).getTitle();
			}
		} catch (KeyNotFoundException e) {
			logger.info("DepartmentUtil getDepartmentName can't find department, maybe the department is not imported");
			logger.info("defaultDepartmentName "+ defaultDepartmentName +" will return");
			return defaultDepartmentName;
		} catch (PersistenceException e) {
			logger.info("DepartmentUtil getDepartmentName persistenceException");
			logger.info("defaultDepartmentName "+ defaultDepartmentName +" will return");
			return defaultDepartmentName;
		}
		
	}
	
	public static String getDepartmentIdByUserId(String userId){
		User user = null;
		try {
			userDbLoader.loadById(Id.generateId(User.DATA_TYPE, userId));
		} catch (KeyNotFoundException e) {
			logger.info("User can't be found");
			e.printStackTrace();
		} catch (PersistenceException e) {
			logger.info("Load user failed");
			e.printStackTrace();
		}
		return getDepratmentIdByUser(user);
	}
	
	public static String getDepratmentIdByUser(User user){	
		if(isPortal()){
			PortalRole pr = null;
			try {
				pr = portalRoleDbLoader.loadPrimaryRoleByUserId(user.getId());
			} catch (PersistenceException e) {
				logger.info("Load PortalRole failed");
				e.printStackTrace();
			}
			return pr.getRoleID();
		}
		else {
			String departmentName = user.getFamilyName();
			return departmentName;
		}		
	}
	
	public static String appendSilkCategorySuffix(String originalDepartmentId){
		String fixedDepartmentId = "";
		if(CommonConfigLoader.isSilkSuffixAppended()){
			fixedDepartmentId = originalDepartmentId + CommonConfigLoader.getSilkCategorySuffix();
		}
		else 
			fixedDepartmentId = originalDepartmentId;
		return fixedDepartmentId;
	}
	
	public static String appendSilkPortalRoleSuffix(String originalDepartmentId){
		String fixedDepartmentId = "";
		if(CommonConfigLoader.isSilkSuffixAppended()){
			fixedDepartmentId = originalDepartmentId + CommonConfigLoader.getSilkPortalRoleSuffix();
		}
		else 
			fixedDepartmentId = originalDepartmentId;
		return fixedDepartmentId;
	}
	
	public static Status updateDepartmentByNames(DepartmentInfo departmentInfo){	
		String departmentId = departmentInfo.getDepartmentId();
		String departmentName = departmentInfo.getDepartmentName();
		boolean portalUpdateSuccess = false;
		if(isPortal()){
			PortalRole pr = null;
			departmentId = appendSilkPortalRoleSuffix(departmentId);
			try {
				pr = portalRoleDbLoader.loadByRoleName(departmentName);
				pr.setRoleID(departmentId);
				if(ExtentionAttributeUtil.hasExtention(pr, departmentInfo)){
					ExtentionAttributeUtil.setExtentionAttribute(pr, departmentInfo);
				}
				DataSourceKeyUtil.setDataSrouceKey(pr, departmentInfo);
				portalRoleDbPersister.persist(pr);
				portalUpdateSuccess = true;
			} catch (PersistenceException e) {
				logger.info("Load PortalRole failed");
				e.printStackTrace();
				return Status.UpdateFailed;
			} catch (ValidationException e) {
				logger.info("ValidationException Load PortalRole failed");
				e.printStackTrace();
				return Status.UpdateFailed;
			}
		}		
		BbCourseCategory bbcc = null;
		departmentId = appendSilkCategorySuffix(departmentId);
		try {
			bbcc = courseCategoryDbLoader.loadByTitle(departmentName);
			bbcc.setBatchUid(departmentId);
			if(ExtentionAttributeUtil.hasExtention(bbcc, departmentInfo)){
				ExtentionAttributeUtil.setExtentionAttribute(bbcc, departmentInfo);
			}
			DataSourceKeyUtil.setDataSrouceKey(bbcc, departmentInfo);
			courseCategoryDbPersister.persist(bbcc);
			return Status.UpdateSuccess;
		} catch (KeyNotFoundException e) {
			logger.info("Load BbCourseCategory failed");
			e.printStackTrace();
			if(portalUpdateSuccess)
				return Status.PortalSuccessButCatalogFailed;
			return Status.UpdateFailed;
		} catch (PersistenceException e) {
			logger.info("Load BbCourseCategory failed");
			e.printStackTrace();
			if(portalUpdateSuccess)
				return Status.PortalSuccessButCatalogFailed;
			return Status.UpdateFailed;
		} catch (ValidationException e) {
			logger.info("Validate BbCourseCategory failed");
			e.printStackTrace();
			if(portalUpdateSuccess)
				return Status.PortalSuccessButCatalogFailed;
			return Status.UpdateFailed;
		}			
	}
}
